﻿// Sequin.WebLogs.LogEntry
//
// (c) 2011 Arthur Pitman
//
// Part of the Sequin Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License (Version 2.1) as published by the Free Software Foundation.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License (Version 2.1) along with this library; if not, write to the 
// Free Software Foundation, Inc., 
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
// or see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sequin.WebLogs
{
    /// <summary>
    /// Represents a web log file entry
    /// </summary>
    public class LogEntry
    {
        /// <summary>
        /// The timestamp associated with the <see cref="LogEntry"/>
        /// </summary>
        public DateTime TimeStamp { get; protected set; }
        
        /// <summary>
        /// The <see cref="HttpRequestType"/> associated with the <see cref="LogEntry"/>
        /// </summary>
        public HttpRequestType RequestType { get; protected set; }
        
        /// <summary>
        /// The request associated with the <see cref="LogEntry"/>
        /// </summary>
        public string Request { get; protected set; }
        
        /// <summary>
        /// The HTTP response code associated with the <see cref="LogEntry"/>
        /// </summary>
        public int ResponseCode { get; protected set; }
        
        /// <summary>
        /// The referrer associated with the <see cref="LogEntry"/>
        /// </summary>
        public string Referrer { get; protected set; }

        /// <summary>
        /// The <see cref="UserIdentity"/> associated with the <see cref="LogEntry"/>
        /// </summary>
        public UserIdentity Identity { get; protected set; }

        /// <summary>
        /// Initializes a new <see cref="LogEntry"/> instance
        /// </summary>
        /// <param name="timeStamp">The timestamp associated with the <see cref="LogEntry"/></param>
        /// <param name="requestType">The <see cref="HttpRequestType"/> associated with the <see cref="LogEntry"/></param>
        /// <param name="request">The request associated with the <see cref="LogEntry"/></param>
        /// <param name="responseCode">The response code associated with the <see cref="LogEntry"/></param>
        /// <param name="referrer">The referrer associated with the <see cref="LogEntry"/></param>
        /// <param name="identity">The <see cref="UserIdentity"/> associated with the <see cref="LogEntry"/></param>
        public LogEntry(DateTime timeStamp,
            HttpRequestType requestType,
            string request,
            int responseCode,
            string referrer,
            UserIdentity identity)
        {
            TimeStamp = timeStamp;
            RequestType = requestType;
            Request = request;
            ResponseCode = responseCode;
            Referrer = referrer;
            Identity = identity;
        }

        /// <summary>
        /// Enumeration representing various HTTP request types
        /// </summary>
        public enum HttpRequestType
        {
            /// <summary>
            /// GET HTTP request
            /// </summary>
            Get,

            /// <summary>
            /// HEAD HTTP request
            /// </summary>
            Head,

            /// <summary>
            /// POST HTTP request
            /// </summary>
            Post,

            /// <summary>
            /// Unknown HTTP request, for completeness
            /// </summary>
            Unknown
        }

        /// <summary>
        /// Converts a <see cref="string"/> into an <see cref="HttpRequestType"/>
        /// </summary>
        /// <param name="requestTypeString">The string to convert</param>
        /// <returns>An <see cref="HttpRequestType"/></returns>
        public static HttpRequestType GetRequestType(string requestTypeString)
        {
            if (requestTypeString.Equals("get"))
                return HttpRequestType.Get;
            else if (requestTypeString.Equals("head"))
                return HttpRequestType.Head;
            else if (requestTypeString.Equals("post"))
                return HttpRequestType.Post;
            else
                return HttpRequestType.Unknown;
        }

        /// <summary>
        /// Converts an <see cref="HttpRequestType"/> into a <see cref="string"/>
        /// </summary>
        /// <param name="requestType">The <see cref="HttpRequestType"/> to convert</param>
        /// <returns>A <see cref="string"/></returns>
        public static string GetRequestType(HttpRequestType requestType)
        {            
            if (requestType == HttpRequestType.Get)
                return "get";
            else if (requestType == HttpRequestType.Head)
                return "head";
            else if (requestType == HttpRequestType.Post)
                return "post";
            else
                return "unknown";
        }

        /// <summary>
        /// Converts this <see cref="LogEntry"/> to a <see cref="string"/>
        /// </summary>
        /// <returns>The resulting <see cref="string"/></returns>
        public override string ToString()
        {
            StringBuilder s = new StringBuilder();
            s.Append(Identity.Ip.ToString());
            s.Append(" ");
            s.Append(TimeStamp.ToString("s"));
            s.Append(" ");
            s.Append(GetRequestType(RequestType));
            s.Append(" ");
            s.Append(Request);
            s.Append(" ");
            s.Append(ResponseCode);
            s.Append(" ");
            s.Append(Referrer);
            s.Append(" ");
            s.Append(UserIdentity.GetUserAgentById(Identity.UserAgentId));
            return s.ToString();
        }

    }
}
